package com.bungarus;

import com.bungarus.busi.BusiServerChildHandlerInitializer;
import com.bungarus.busi.StatusContainer;
import com.bungarus.cluster.ClusterManager;
import com.bungarus.config.BungarusSpringConfig;
import com.bungarus.model.AbstractBungarusServer;
import io.netty.channel.ChannelHandler;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.data.mongodb.core.MongoTemplate;

/**
 * Created by tang on 2018/11/25.
 */
public class Busi extends AbstractBungarusServer {
    public static final String TAG = "busi";
    /**
     * communication port with nodes in transfer cluster
     */
    private static final int PORT_7900 = 7900;
    /**
     * communication port with nodes in access cluster
     */
    private static final int PORT_7850 = 7850;
    /**
     * communication port with nodes in other busi cluster
     * provide service to retrieve the receipt's session info for other busi cluster
     */
    private static final int PORT_8000 = 8000;
    /**
     * the cluster to which busi node will connect as client
     * the busi cluster will dispatch the message to receipt
     */
    public static final String CLUSTER_TAG_ACCESS = "access";
    /**
     * the cluster name array to which busi node will connect as client
     */
    private static final String[] CLUSTER_TAGS = {CLUSTER_TAG_ACCESS};
    /**
     * cluster manager which manages the specific (named by TAG) cluster
     */
    private ClusterManager clusterManager = new ClusterManager(TAG);
    /**
     * spring context
     */
    private static final ApplicationContext springContext =
            new AnnotationConfigApplicationContext(BungarusSpringConfig.class);

    public static void main(String[] args) throws Exception {
        int[] messagePorts = {PORT_7900, PORT_7850, PORT_8000};

        Busi busi = new Busi();
        busi.bind(messagePorts, null);
        busi.initClusterAndConnectRemoteNode();
        busi.initRemedy();
        busi.listen(value -> {
            StatusContainer.close();
            return null;
        });
    }

    @Override
    public ClusterManager getClusterManager() {
        return clusterManager;
    }

    @Override
    public ChannelHandler getChildHandlerInitializer() {
        return new BusiServerChildHandlerInitializer(this);
    }

    @Override
    protected MongoTemplate getMongoTemplate4FailedRetry() {
        return (MongoTemplate) springContext.getBean("mongoTemplate");
    }

    @Override
    public String[] getRemoteNodeTags() {
        return CLUSTER_TAGS;
    }

    @Override
    public String getTag() {
        return TAG;
    }

    @Override
    public String tagPortString4Connection() {
        return "(access|7850,transfer|7900)";
    }
}
